package com.easyOrder.core.json;

import com.easyOrder.core.exception.api.HttpMessageConverterException;
import com.easyOrder.core.json.probe.ObjectProbe;
import com.easyOrder.core.utils.ParametersUtil;
import com.easyOrder.core.utils.ObjectUtil;
import org.apache.log4j.Logger;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;

public class ObjectFormHttpMessageConverter implements
		HttpMessageConverter<Object> {
	
	private Logger logger = Logger.getLogger(ObjectFormHttpMessageConverter.class);
	
	private List<MediaType> supportedMediaTypes;

	public ObjectFormHttpMessageConverter() {
		supportedMediaTypes = new ArrayList<MediaType>();
		supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
		supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
	}

	public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes) {
		this.supportedMediaTypes = supportedMediaTypes;
	}

	public List<MediaType> getSupportedMediaTypes() {
		return Collections.unmodifiableList(this.supportedMediaTypes);
	}

	public boolean canRead(Class<?> clazz, MediaType mediaType) {
		if (null == mediaType) {
			return true;
		}
		for (MediaType supportedMediaType : getSupportedMediaTypes()) {
			if (supportedMediaType.includes(mediaType)) {
				return true;
			}
		}
		return false;
	}

	public boolean canWrite(Class<?> clazz, MediaType mediaType) {
		return false;
	}

	public Object read(Class<?> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException {
		HttpServletRequest request = getRequest();
		try {
			Object obj = clazz.newInstance();
			ObjectProbe objectProbe = ObjectUtil.getProbe(obj);
			Map<String, String> parameters = ParametersUtil.getParameters(request);
			if (null != parameters) {
				Iterator<Map.Entry<String, String>> iterator = parameters
						.entrySet().iterator();
				while (iterator.hasNext()) {
					Map.Entry<String, String> entry = iterator.next();
					String parameterName = entry.getKey();
					String parameterValue = entry.getValue();
					objectProbe.setValue(parameterName, parameterValue);
				}
			}
			return obj;
		} catch (Exception e) {
			logger.error(e, e);
			throw new HttpMessageConverterException(e);
		}
	}

	public void write(Object t, MediaType contentType,
			HttpOutputMessage outputMessage) throws IOException,
			HttpMessageNotWritableException {
	}

	private HttpServletRequest getRequest() {
		return ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
	}
}
